﻿#pragma once

/*
    字节序交换处理模块：
         由于网络通信一般采用BIG字节序\也叫做网络字节序.
         我们使用的PC机或者嵌入式系统可能使用BIG字节序也可能使用LITTEN(小字节序)
         所以我们必须在此之间做一个字节序的转换。
*/
#include "common/basictypes.h"
#include <algorithm>

namespace KBEngineClient
{
	/*
	小端时返回true
	*/
	bool isPlatformLittleEndian()
	{
		int n = 1;
		return *((char*)&n) ? true : false;
	}

	static bool IS_PLATFORM_LITTLE_ENDIAN = isPlatformLittleEndian();

	namespace MemoryStreamConverter
	{
		template<size_t T>
		inline void convert(char *val)
		{
			std::swap(*val, *(val + T - 1));
			convert<T - 2>(val + 1);
		}

		template<> inline void convert<0>(char *) {}
		template<> inline void convert<1>(char *) {}            // ignore central byte

		template <typename T>
		inline void apply(T *val)
		{
			convert<sizeof(T)>((char *)(val));
		}

		inline void convert(char *val, size_t size)
		{
			if (size < 2)
				return;

			std::swap(*val, *(val + size - 1));
			convert(val + 1, size - 2);
		}
	}

	template <typename T>
	inline void EndianConvert(T &val)
	{
		if (!IS_PLATFORM_LITTLE_ENDIAN)
			MemoryStreamConverter::apply<T>(&val);
	}

	template <typename T>
	inline void EndianConvertReverse(T &val)
	{
		if (IS_PLATFORM_LITTLE_ENDIAN)
			MemoryStreamConverter::apply<T>(&val);
	}

	template <typename T> void EndianConvert(T *); // will generate link error
	template <typename T> void EndianConvertReverse(T *); // will generate link error

	inline void EndianConvert(uint8 &) {}
	inline void EndianConvert(int8 &) {}
	inline void EndianConvertReverse(uint8 &) {}
	inline void EndianConvertReverse(int8 &) {}
}
